home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / shells / bashsrc.zoo / make_cmd.c < prev    next >
C/C++ Source or Header  |  1991-06-05  |  14KB  |  543 lines

  1. /* make_command.c --
  2.    Functions for making instances of the various parser constructs. */
  3.  
  4. /* Copyright (C) 1989 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  21.  
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #ifndef SONY
  25. #include <fcntl.h>
  26. #endif
  27. #include <sys/file.h>
  28.  
  29. #if defined (HAVE_VPRINTF)
  30. #include <varargs.h>
  31. #endif
  32.  
  33. #include "shell.h"
  34. #include "flags.h"
  35.  
  36. WORD_DESC *
  37. make_word (string)
  38.      char *string;
  39. {
  40.   WORD_DESC *temp = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
  41.   temp->word = savestring (string);
  42.   temp->quoted = temp->dollar_present = temp->assignment = 0;
  43.   while (*string) {
  44.     if (*string == '$') temp->dollar_present = 1;
  45.  
  46.     if (member (*string, "'`\\\""))
  47.       {
  48.     temp->quoted = 1;
  49.     if (*string == '\\')
  50.       string++;
  51.       }
  52.     if (*string)
  53.       (string++);
  54.   }
  55.   return (temp);
  56. }
  57.  
  58. WORD_DESC *
  59. make_word_from_token (token)
  60.      int token;
  61. {
  62.   char tokenizer[2];
  63.  
  64.   tokenizer[0] = token;
  65.   tokenizer[1] = '\0';
  66.  
  67.   return (make_word (tokenizer));
  68. }
  69.  
  70. WORD_LIST *
  71. make_word_list (word, link)
  72.      WORD_DESC *word;
  73.      WORD_LIST *link;
  74. {
  75.   WORD_LIST *temp = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
  76.   temp->word = word;
  77.   temp->next = link;
  78.   return (temp);
  79. }
  80.  
  81. WORD_LIST *
  82. add_string_to_list (string, list)
  83.      char *string;
  84.      WORD_LIST *list;
  85. {
  86.   WORD_LIST *temp = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
  87.   temp->word = make_word (string);
  88.   temp->next = list;
  89.   return (temp);
  90. }
  91.  
  92. WORD_DESC *
  93. coerce_to_word (number)
  94.      int number;
  95. {
  96.   char *string = (char *)alloca (24);
  97.   sprintf (string, "%d", number);
  98.   return (make_word (string));
  99. }
  100.  
  101. COMMAND *
  102. make_command (type, pointer)
  103.      enum command_type type;
  104.      SIMPLE_COM *pointer;
  105. {
  106.   COMMAND *temp = (COMMAND *)xmalloc (sizeof (COMMAND));
  107.   temp->type = type;
  108.   temp->value.Simple = pointer;
  109.   temp->subshell = 0;
  110.   temp->redirects = (REDIRECT *)NULL;
  111.   return (temp);
  112. }
  113.  
  114. COMMAND *
  115. command_connect (com1, com2, connector)
  116.      COMMAND *com1, *com2;
  117.      int connector;
  118. {
  119.   CONNECTION *temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
  120.   temp->connector = connector;
  121.   temp->first = com1;
  122.   temp->second = com2;
  123.   return (make_command (cm_connection, temp));
  124. }
  125.  
  126. COMMAND *
  127. make_for_command (name, map_list, action)
  128.      WORD_DESC *name;
  129.      WORD_LIST *map_list;
  130.      COMMAND *action;
  131. {
  132.   FOR_COM *temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
  133.  
  134.   temp->name = name;
  135.   temp->map_list = map_list;
  136.   temp->action = action;
  137.   return (make_command (cm_for, temp));
  138. }
  139.  
  140. COMMAND *
  141. make_group_command (command)
  142.      COMMAND *command;
  143. {
  144.   GROUP_COM *temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
  145.  
  146.   temp->command = command;
  147.   return (make_command (cm_group, temp));
  148. }
  149.  
  150. COMMAND *
  151. make_case_command (word, clauses)
  152.      WORD_DESC *word;
  153.      PATTERN_LIST *clauses;
  154. {
  155.   WORD_LIST *reverse_list ();
  156.   CASE_COM *temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
  157.   temp->word = word;
  158.   temp->clauses = (PATTERN_LIST *)reverse_list (clauses);
  159.   return (make_command (cm_case, temp));
  160. }
  161.  
  162. PATTERN_LIST *
  163. make_pattern_list (patterns, action)
  164.      WORD_LIST *patterns;
  165.      COMMAND *action;
  166. {
  167.   PATTERN_LIST *temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
  168.   temp->patterns = patterns;
  169.   temp->action = action;
  170.   temp->next = NULL;
  171.   return (temp);
  172. }
  173.  
  174. COMMAND *
  175. make_if_command (test, true_case, false_case)
  176.      COMMAND *test, *true_case, *false_case;
  177. {
  178.   IF_COM *temp = (IF_COM *)xmalloc (sizeof (IF_COM));
  179.   temp->test = test;
  180.   temp->true_case = true_case;
  181.   temp->false_case = false_case;
  182.   return (make_command (cm_if, temp));
  183. }
  184.  
  185. COMMAND *
  186. make_until_or_while (test, action, which)
  187.      COMMAND *test, *action;
  188.      enum command_type which;
  189. {
  190.   WHILE_COM *temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
  191.   temp->test = test;
  192.   temp->action = action;
  193.   return (make_command (which, temp));
  194. }
  195.  
  196. COMMAND *
  197. make_while_command (test, action)
  198.      COMMAND *test, *action;
  199. {
  200.   return (make_until_or_while (test, action, cm_while));
  201. }
  202.  
  203. COMMAND *
  204. make_until_command (test, action)
  205.      COMMAND *test, *action;
  206. {
  207.   return (make_until_or_while (test, action, cm_until));
  208. }
  209.  
  210. /* Return a command which is the connection of the word or redirection
  211.    in ELEMENT, and the command * or NULL in COMMAND. */
  212. COMMAND *
  213. make_simple_command (element, command)
  214.      ELEMENT element;
  215.      COMMAND *command;
  216. {
  217.   /* If we are starting from scratch, then make the initial command
  218.      structure.  Also note that we have to fill in all the slots, since
  219.      malloc doesn't return zeroed space. */
  220.   if (!command)
  221.     {
  222.       SIMPLE_COM *temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
  223.       temp->words = (WORD_LIST *)NULL;
  224.       temp->redirects = (REDIRECT *)NULL;
  225.       command = (COMMAND *)xmalloc (sizeof (COMMAND));
  226.       command->type = cm_simple;
  227.       command->redirects = (REDIRECT *)NULL;
  228.       command->subshell = 0;
  229.       command->value.Simple = temp;
  230.     }
  231.   if (element.word)
  232.     {
  233.       WORD_LIST *tw = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
  234.       tw->word = element.word;
  235.       tw->next = command->value.Simple->words;
  236.       command->value.Simple->words = tw;
  237.     }
  238.   else
  239.     {
  240.       element.redirect->next = command->value.Simple->redirects;
  241.       command->value.Simple->redirects = element.redirect;
  242.     }
  243.   return (command);
  244. }
  245.  
  246. /* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION. 
  247.    INSTRUCTION is the instruction type, SOURCE is an INT,
  248.    and DEST is an INT or a WORD_DESC *. */
  249. REDIRECT *
  250. make_redirection (source, instruction, dest)
  251.      enum r_instruction instruction;
  252. {
  253.   REDIRECT *temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
  254.   int kill_leading = 0;
  255.  
  256.   /* First do the common cases. */
  257.   temp->redirector = source;
  258.   temp->redirectee.dest = dest;
  259.   temp->instruction = instruction;
  260.   temp->next = (REDIRECT *)NULL;
  261.  
  262.   switch (instruction) {
  263.  
  264.   case r_output_direction:    /* >foo */
  265.     temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
  266.     break;
  267.  
  268.   case r_input_direction:    /* <foo */
  269.   case r_inputa_direction:    /* foo & makes this. */
  270.     temp->flags = O_RDONLY;
  271.     break;
  272.  
  273.   case r_appending_to:        /* >>foo */
  274.     temp->flags = O_APPEND | O_WRONLY | O_CREAT;
  275.     break;
  276.  
  277.     /* Because we are Bourne compatible, we read the input for this
  278.        << or <<- redirection now, from wherever input is coming from.
  279.        We store the input read into a WORD_DESC.  Replace the text of
  280.        the redirectee.word with the new input text.  If <<- is on,
  281.        then remove leading whitespace from each line. */
  282.  
  283.   case r_deblank_reading_until:    /* <<-foo */
  284.     kill_leading++;
  285.     /* ... */
  286.   case r_reading_until:        /* <<foo */
  287.     {
  288.       char *redirection_expand (), *redirectee_word;
  289.       int len;
  290.  
  291.       char *document = (char *)NULL;
  292.       int document_index = 0, document_size = 0;
  293.  
  294.       /* Because of Bourne shell semantics, we turn off globbing, but
  295.      only for this style of redirection.  I feel a little ill.  */
  296.       {
  297.     extern int disallow_filename_globbing;
  298.     int old_value = disallow_filename_globbing;
  299.     disallow_filename_globbing = 1;
  300.  
  301.     redirectee_word = redirection_expand (temp->redirectee.filename);
  302.  
  303.     disallow_filename_globbing = old_value;
  304.       }
  305.  
  306.       len = strlen (redirectee_word);
  307.       free (temp->redirectee.filename->word);
  308.       temp->here_doc_eof = redirectee_word;
  309.  
  310.       /* Re